package com.example.springboottest.example.netty.nien.json;

import com.example.springboottest.example.nio.udp.UDPClient;
import com.example.springboottest.example.serialize.nien.JsonMsg;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

/**
 * 执行次序是：先启动服务器端，然后启动客户端。启动后，客户端会向服务器发送 1000 个 POJO
 * 转换成 JSON 后的字符串。如果能从服务器的控制台看到输出的 JSON 格式的字符串，说明程序运
 * 行是正确的。
 */
public class JsonSendClient {
    static String content = "疯狂创客圈：高性能学习社群!";
    private int serverPort;
    private String serverIp;
    Bootstrap b = new Bootstrap();

    public JsonSendClient(String ip, int port) {
        this.serverPort = port;
        this.serverIp = ip;
    }

    public void runClient() {
        //创建反应器线程组
        EventLoopGroup workerLoopGroup = new NioEventLoopGroup();
        try {
            //1 设置反应器线程组
            b.group(workerLoopGroup);
            //2 设置 nio 类型的通道
            b.channel(NioSocketChannel.class);
            //3 设置监听端口
            b.remoteAddress(serverIp, serverPort);
            //4 设置通道的参数
            b.option(ChannelOption.ALLOCATOR,
                    PooledByteBufAllocator.DEFAULT);
            //5 装配通道流水线
            b.handler(new ChannelInitializer<SocketChannel>() {
                //初始化客户端通道
                protected void initChannel(SocketChannel ch) throws Exception {
                    // 客户端通道流水线添加 2 个 Handler 业务处理器
                    ch.pipeline().addLast(new LengthFieldPrepender(4));
                    ch.pipeline().addLast(new
                            StringEncoder(CharsetUtil.UTF_8));
                }
            });
            ChannelFuture f = b.connect();
            f.addListener((ChannelFuture futureListener) ->
            {
                if (futureListener.isSuccess()) {
                    System.out.println("EchoClient 客户端连接成功!");
                } else {
                    System.out.println("EchoClient 客户端连接失败!");
                }
            });
            // 阻塞,直到连接完成
            f.sync();
            Channel channel = f.channel();
            //发送 Json 字符串对象
            for (int i = 0; i < 1000; i++) {
                JsonMsg user = build(i, i + "->" + content);
                channel.writeAndFlush(user.convertToJson());
                System.out.println("发送报文：" + user.convertToJson());
            }
            channel.flush();
            // 7 等待通道关闭的异步任务结束
            // 服务监听通道会一直等待通道关闭的异步任务结束
            ChannelFuture closeFuture = channel.closeFuture();
            closeFuture.sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 从容关闭 EventLoopGroup，
            // 释放掉所有资源，包括创建的线程
            workerLoopGroup.shutdownGracefully();
        }
    }

    //构建 Json 对象
    public JsonMsg build(int id, String content) {
        JsonMsg user = new JsonMsg();
        user.setId(id);
        user.setContent(content);
        return user;
    }

    public static void main(String[] args) throws InterruptedException {
        int port = UDPClient.PORT;
        String ip = UDPClient.IP;
        new JsonSendClient(ip, port).runClient();
    }
}
